/*
 * Copyright (c) 2013, EWELL Techno. All rights reserved.
 */
package p.ithorns.framework.common.time;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
import java.util.*;
import java.util.regex.Pattern;

/**
 * <p>
 * 日期时间工具
 * </p>
 *
 * @author harrin 2017-3-13
 */
public class DateOldUtil {

    private static Logger logger = LoggerFactory.getLogger(DateOldUtil.class);

    private static final long MILLISECONDS_A_DAY = 24 * 3600 * 1000;

    private static final long MILLISECONDS_A_HOUR = 3600 * 1000;

    public static final String MIN_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSSSSSSS";

    public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

    public static final String DEFAULT_DATEFULLTIME_FORMAT = "yyyyMMddHHmmss";

    public static final String DEFAULT_FULLDATETIME_FORMAT = "yyyyMMddHHmmssSSS";

    public static final String DEFAULT_DATEFULLDATE_FORMAT = "yyyyMMdd";

    public static final String DEFAULT_YEAR_FORMAT = "yyyy";

    public static final String DEFAULT_MONTH_FORMAT = "MM";

    public static final String DEFAULT_HOUR_MIN_FORMAT = "HH:mm";

    public static final String REQUESTTIME = "19:00:00";

    private static final Pattern pattern = Pattern.compile("(?:(?:19|20)\\d{2})-(?:0?[1-9]|1[0-2])-(?:0?[1-9]|[12][0-9]|3[01])");

    public static Date addDays(Date date, int days) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, days);
        return cal.getTime();
    }

    public static Date addMinutes(Date date, int minute) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MINUTE, minute);
        return cal.getTime();
    }

    public static Date addSeconds(Date date, int second) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.SECOND, second);
        return cal.getTime();
    }

    public static Date parseDate(String s) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        return format.parse(s);
    }

    public static Date parseDate(String s,String pattern) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.parse(s);
    }

    public static Date parseDate2hms(String s) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.parse(s);
    }

    public static Date addMonths(Date date, int months) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, months);
        return cal.getTime();
    }

    public static Date getMaxDate() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
        return cal.getTime();
    }

    public static int getYear() {
        Calendar cal = Calendar.getInstance();
        return cal.get(Calendar.YEAR);
    }

    public static int getMonth() {
        Calendar cal = Calendar.getInstance();
        return cal.get(Calendar.MONTH) + 1;
    }

    public static Date getMinDate() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DATE, cal.getActualMinimum(Calendar.DATE));
        return cal.getTime();
    }

    public static Date getMinDateByMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DATE, cal.getActualMinimum(Calendar.DATE));
        return cal.getTime();
    }

    public static Date getMaxDateByMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DATE, cal.getActualMaximum(Calendar.DATE));
        return cal.getTime();
    }

    public static Date getLastDayOfLastMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DATE, 1);
        // cal.add(Calendar.MONTH, 1);
        cal.add(Calendar.DATE, -1);
        return cal.getTime();
    }
    public static Date addYears(Date date, int years) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.YEAR, years);
        return cal.getTime();
    }

    public static String datetime(String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(new Date());
    }

    public static String datetime(Date date, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    public static String datetime(String date, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }

    public static String date(Date date, String format) {
        if (date == null) {
            return "";
        }

        return (new SimpleDateFormat(format)).format(date);
    }

    public static String date(String dateStr, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(dateStr);
    }

    public static String getNowDateStr() {
        return getNowDatetimeStr(DEFAULT_DATE_FORMAT);
    }

    public static String getNowDatetimeStr() {
        return getNowDatetimeStr(DEFAULT_DATETIME_FORMAT);
    }

    public static String getNowDateminStr() {
        return getNowDatetimeStr(DEFAULT_DATEFULLTIME_FORMAT);
    }

    public static String getNowDatetimeStr(String format) {
        Calendar cal = Calendar.getInstance();
        return datetime(cal.getTime(), format);
    }

    public static Date dateOnly(Date date) {
        return new Date(date.getTime() / MILLISECONDS_A_DAY);
    }

    public static Date dateOnlyExt(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    public static Date dateMinTime(Date date) {
        return dateOnlyExt(date);
    }

    public static String getStandDateTimeStr(String dateTimeStr) {
        if (dateTimeStr == null || "".equals(dateTimeStr)) {
            return "";
        }

        dateTimeStr = dateTimeStr.replaceAll("\\s+", "|");
        String[] a = dateTimeStr.split("\\|");
        List<String> list = Arrays.asList(a);
        String datetime = "";
        int count = 1;
        for (int i = 0; i < list.size(); i++) {
            String temp = (String) list.get(i);
            StringTokenizer st;
            if (i == 0)
                st = new StringTokenizer(temp, "-");
            else
                st = new StringTokenizer(temp, ":");
            int k = st.countTokens();
            for (int j = 0; j < k; j++) {
                String sttemp = (String) st.nextElement();
                if (count == 1) {
                    datetime = sttemp;
                } else {
                    if ((sttemp.equals("0")) || (sttemp.equals("00")))
                        sttemp = "0";
                    else if ((Integer.valueOf(sttemp).intValue()) < 10)
                        sttemp = sttemp.replaceAll("0", "");
                    if (count < 4) {
                        if ((Integer.valueOf(sttemp).intValue()) < 10)
                            datetime = datetime + "-0" + sttemp;
                        else
                            datetime = datetime + "-" + sttemp;
                    }
                    if (count == 4) {
                        if ((Integer.valueOf(sttemp).intValue()) < 10)
                            datetime = datetime + " 0" + sttemp;
                        else
                            datetime = datetime + " " + sttemp;
                    }
                    if (count > 4) {
                        if ((Integer.valueOf(sttemp).intValue()) < 10)
                            datetime = datetime + ":0" + sttemp;
                        else
                            datetime = datetime + ":" + sttemp;
                    }
                }
                count++;
            }
        }

        try {
            @SuppressWarnings("unused")
            Date test = getDateFromStr(datetime);
            return datetime;
        } catch (Exception e) {
            return "";
        }
    }

    @SuppressWarnings("deprecation")
    public static Date getDateFromStr(String datetime) {
        if (datetime == null || "".equals(datetime)) {
            return null;
        }

        String nyr = datetime.trim();

        if (nyr.indexOf(" ") > 0) {
            nyr = nyr.substring(0, nyr.indexOf(" "));
        } else {
            nyr = nyr.substring(0, nyr.length());
        }

        StringTokenizer st = new StringTokenizer(nyr, "-");
        Date date = new Date();
        String temp = "";
        int count = st.countTokens();
        for (int i = 0; i < count; i++) {
            temp = (String) st.nextElement();
            // if(!(temp.equals("0")))
            // temp.replaceAll("0", "");
            if (i == 0)
                date.setYear(Integer.parseInt(temp) - 1900);
            if (i == 1)
                date.setMonth(Integer.parseInt(temp) - 1);
            if (i == 2)
                date.setDate(Integer.parseInt(temp));
        }

        if (datetime.length() > 10) {
            String sfm = datetime.substring(11, 19);
            StringTokenizer st2 = new StringTokenizer(sfm, ":");
            count = st2.countTokens();
            for (int i = 0; i < count; i++) {
                temp = (String) st2.nextElement();
                // if(!(temp.equals("0")))
                // temp.replaceAll("0", "");
                if (i == 0)
                    date.setHours(Integer.parseInt(temp));
                if (i == 1)
                    date.setMinutes(Integer.parseInt(temp));
                if (i == 2)
                    date.setSeconds(Integer.parseInt(temp));
            }
        }
        return date;
    }

    public static int getQuot(Date startDate, Date endDate) {
        long quot = 0;
        quot = endDate.getTime() - startDate.getTime();
        quot = quot / MILLISECONDS_A_DAY;
        return (int) quot;
    }

    public static int getQuot(String startDateStr, String endDateStr, String format) {
        long quot = 0;
        format = (format != null && format.length() > 0) ? format : DEFAULT_DATE_FORMAT;
        SimpleDateFormat ft = new SimpleDateFormat(format);
        try {
            Date date1 = ft.parse(endDateStr);
            Date date2 = ft.parse(startDateStr);
            quot = date1.getTime() - date2.getTime();
            quot = quot / MILLISECONDS_A_DAY;
        } catch (ParseException e) {
            logger.error("", e);
        }
        return (int) quot;
    }

    public static final String getDateTime(Date date) {
        if (date == null)
            return "";
        DateFormat ymdhmsFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        return ymdhmsFormat.format(date);
    }

    public static final String getDateTime(Date date, String pattern) {
        if (date == null)
            return "";
        DateFormat ymdhmsFormat = new SimpleDateFormat(pattern);
        return ymdhmsFormat.format(date);
    }

    public static int getQuotHours(Date startDate, Date endDate) {
        long quot = 0;
        quot = endDate.getTime() - startDate.getTime();
        quot = quot / MILLISECONDS_A_HOUR;
        return (int) quot;
    }

    public static Date getDateTime(String dateTime) {
        return getDateTime(dateTime, "yyyy-MM-dd");
    }

    public static Date getDateTime(String dateTime, String formatPattern) {
        try {
            if (StringUtils.isNotBlank(dateTime) && StringUtils.isNotBlank(formatPattern)) {
                SimpleDateFormat format = new SimpleDateFormat(formatPattern);
                return format.parse(dateTime);
            }
        } catch (ParseException e) {
            logger.error(e.getMessage(), e);
        }

        return null;
    }

    public static Date getDateDetailTime(String dateTime) {
        try {
            if (StringUtils.isNotBlank(dateTime)) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                return format.parse(dateTime);
            }
        } catch (ParseException e) {
            logger.error(e.getMessage(), e);
        }

        return null;
    }

    public static Date getDateDetailTime2(String dateTime) {
        try {
            if (StringUtils.isNotBlank(dateTime)) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");

                return format.parse(dateTime);
            }
        } catch (ParseException e) {
            logger.error(e.getMessage(), e);
        }

        return null;
    }

    public static long getDtSeq() {
        return System.currentTimeMillis();
    }

    public static boolean isBetween(Date min, Date compare) {
        Boolean ret = false;
        Date minDate = DateOldUtil.dateOnlyExt(min);
        Date maxDate = DateOldUtil.dateOnlyExt(DateOldUtil.addDays(min, 1));
        if (compare.after(minDate) && compare.before(maxDate)) {
            ret = true;
        }
        return ret;
    }

    public static Date getDate(int year, int month, int day) {
        Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, day);
        return cal.getTime();
    }

    public static Map<String, String> getFLDayMap(String monthRange) {
        return getFLDayMap(monthRange, DEFAULT_DATE_FORMAT);
    }

    public static Map<String, String> getFLDayMap(String monthRange, String pattern) {
        Map<String, String> rs = new LinkedHashMap<String, String>();

        SimpleDateFormat df = new SimpleDateFormat(pattern);
        GregorianCalendar calendar = new GregorianCalendar();
        calendar.setTime(new Date());

        if (StringUtils.isBlank(monthRange)) {
            monthRange = "cm";
        }

        if (!"sm".equals(monthRange)) {
            if ("pm".equals(monthRange)) {
                calendar.add(Calendar.MONTH, -1);
            }

            calendar.set(Calendar.DAY_OF_MONTH, 1);
            rs.put("firstDay", df.format(calendar.getTime()));

            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
            rs.put("lastDay", df.format(calendar.getTime()));

            return rs;
        }

        int[][] seasons = {{2, 4}, {5, 7}, {8, 10}, {11, 1}};
        int cm = calendar.get(Calendar.MONTH) + 1;

        for (int[] im : seasons) {
            if (cm >= im[0] && cm <= im[1]) {
                calendar.set(Calendar.MONTH, im[0] - 1);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                rs.put("firstDay", df.format(calendar.getTime()));

                calendar.set(Calendar.MONTH, im[1] - 1);
                calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
                rs.put("lastDay", df.format(calendar.getTime()));

                break;
            }
        }

        return rs;
    }

    public static String getYearString(Date date) {
        return DateOldUtil.date(date, DEFAULT_YEAR_FORMAT);
    }

    public static int getYearInteger(Date date) {
        return Integer.parseInt(DateOldUtil.date(date, DEFAULT_YEAR_FORMAT));
    }

    public static String getMonthString(Date date) {
        return DateOldUtil.date(date, DEFAULT_MONTH_FORMAT);
    }

    public static int getMonthInteger(Date date) {
        return Integer.parseInt(DateOldUtil.date(date, DEFAULT_MONTH_FORMAT));
    }

    public static Date getLastDayOfCurMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month);
        cal.set(Calendar.DATE, 1);
        // cal.add(Calendar.MONTH, 1);
        cal.add(Calendar.DATE, -1);
        return cal.getTime();
    }

    public static Date getFirstDayOfCurMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DATE, 1);
        // cal.add(Calendar.MONTH, 1);
        cal.add(Calendar.DATE, 0);
        return cal.getTime();
    }

    public static Date getFirstDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
        return c.getTime();
    }

    public static Date getLastDayOfWeek(Date date) {
        Calendar c = new GregorianCalendar();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(date);
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek() + 6);
        return c.getTime();
    }

    public static boolean isValidDate(String ds) {
        if (StringUtils.isBlank(ds))
            return false;
        return pattern.matcher(ds).matches();
    }

    public static boolean isValidDate(Date d) {
        if (d == null)
            return false;
        return pattern.matcher(date(d, DEFAULT_DATE_FORMAT)).matches();
    }

    /**
     * <p>
     * 医嘱拆分中的今天（护理系统提供的函数）
     * </p>
     *
     * @return 当天
     */
    public static Date getToday() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        Date today = calendar.getTime();
        calendar.add(Calendar.DAY_OF_YEAR, 2);
        calendar.set(Calendar.HOUR_OF_DAY, 8);
        calendar.add(Calendar.SECOND, -1);
        return today;
    }

    /**
     * <p>
     * 根据生日计算出年龄
     * </p>
     *
     * @param birthday
     * @return 年龄
     */
    public static String getSimpleAgeByBirthDay(Date birthday) {
        return convertToAgeEx(new Date(), birthday, true);
    }

    /**
     * <p>
     * 根据生日计算出年龄
     * </p>
     *
     * @param birthday
     * @return 年龄
     */
    public static String getFullAgeByBirthDay(Date birthday) {
        return convertToAgeEx(new Date(), birthday, true);
    }

    /**
     * 拼接年龄字符串
     *
     * @param year
     * @param month
     * @param day
     * @param simply
     * @return
     */
    private static String toAgeFullString(int year, int month, int day, boolean simply) {
        StringBuilder sb = new StringBuilder();
        if (year > 0) {
            sb.append(year + "岁");
            if (year > 1) {
                return year + "岁";
            } else {
                return year + "岁" + month + "月";
            }
        }

        if (month > 0) {
            sb.append(month + "月");
            if (simply) {
                return month + "月";
            }
        }

        if (day > 0) {
            sb.append(day + "天");
            if (simply) {
                return day + "天";
            }
        }

        return sb.toString();
    }

    /**
     * 获取年龄
     *
     * @param now
     * @param birthday
     * @param simply   是否取最大计量单位的值，例20岁，3月，5天等。。 为true就取20岁，为false就全部取
     * @return
     */
    private static String convertToAgeEx(Date now, Date birthday, boolean simply) {
        // 当前时间
        Calendar cNow = Calendar.getInstance();
        cNow.setTime(now);
        // 出生时间
        Calendar cBirthday = Calendar.getInstance();
        cBirthday.setTime(birthday);

        // 出生天数
        long days = (now.getTime() - birthday.getTime()) / (24 * 60 * 60 * 1000);

        // 小于一周时，按新生儿处理
        if (days < 7) {
            // 新生儿计算小时
            return convertToBabyAge(now, birthday, simply);
        }

        // 当前的年月日
        int nMonth = cNow.get(Calendar.MONTH) + 1;
        int nDay = cNow.get(Calendar.DAY_OF_MONTH);

        // 出生年月日
        int bMonth = cBirthday.get(Calendar.MONTH) + 1;
        int bDay = cBirthday.get(Calendar.DAY_OF_MONTH);

        // 计算日的差值
        int day = nDay - bDay;

        // 相差天数为负值，月减1，考虑2月份的特殊情况
        if (day < 0) {
            if (bMonth == 2 && bDay == 29 // 出生为2.29
                    && nMonth == 2 && nDay == 28) // 当前为2.28
            {
                day = 0;
            } else {
                Calendar c1 = Calendar.getInstance();
                c1.set(4, bMonth, bDay);

                Calendar c2 = Calendar.getInstance();
                c2.set(4, bMonth, nDay);
                c2.add(Calendar.MONTH, 1);

                day = (int) (c2.getTimeInMillis() - c1.getTimeInMillis()) / (24 * 60 * 60 * 1000);

                cNow.add(Calendar.MONTH, -1);
            }
        }

        // 可能发生变化后的年月
        nMonth = cNow.get(Calendar.MONTH);

        // 计算月的差值
        int month = cNow.get(Calendar.MONTH) - cBirthday.get(Calendar.MONTH);

        // 月为负值，年减1
        if (month < 0) {
            month = month + 12;

            cNow.add(Calendar.YEAR, -1);
        }

        // 计算年
        int year = cNow.get(Calendar.YEAR) - cBirthday.get(Calendar.YEAR);
        return toAgeFullString(year, month, day, simply);
    }

    /**
     * 新生宝宝计算出生，按天、小时、分
     *
     * @param now
     * @param birthday
     * @param simply
     * @return
     */
    private static String convertToBabyAge(Date now, Date birthday, boolean simply) {
        long ms = now.getTime() - birthday.getTime();
        StringBuilder sb = new StringBuilder();
        if (ms / (24 * 60 * 60 * 1000) > 0) {
            sb.append(ms / (24 * 60 * 60 * 1000) + "天");
            if (simply) {
                return ms / (24 * 60 * 60 * 1000) + "天";
            }
        }

        if (ms / (60 * 60 * 1000) > 0) {
            sb.append(ms / (60 * 60 * 1000) + "小时");
            if (simply) {
                return ms / (60 * 60 * 1000) + "小时";
            }
        }

        if (ms / (60 * 1000) > 0) {
            sb.append(ms / (60 * 1000) + "分");
            if (simply) {
                return ms / (60 * 1000) + "分";
            }
        }
        return sb.toString();
    }

    /**
     * 获取今天指定的时间
     *
     * @param time
     */
    public static Date getDateByDateAndTimeStr(Date date, String time) {
        String dateStr = DateOldUtil.date(date, DateOldUtil.DEFAULT_DATE_FORMAT);
        return DateOldUtil.getDateTime(dateStr + " " + time, DateOldUtil.DEFAULT_DATETIME_FORMAT);
    }


    /**
     *  根据传入时间 获取上周一时间
     * @return
     */
    public static String getLastWeekMonday() {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        Calendar  cal = Calendar.getInstance();
        cal.setTime(new Date());
        if (1 == cal.get(Calendar.DAY_OF_WEEK)) {//判断当前日期是否为周末，因为周末是本周第一天，如果不向后推迟一天的到的将是下周一的零点，而不是本周周一零点
            cal.add(Calendar.DATE, -1);
        }
        cal.add(Calendar.DAY_OF_MONTH, -7);//时间减去7天
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);//Calendar.MONDAY 这个是周一的意思      想获取周几就更换这个
        return format.format(cal.getTime());
    }

    /**
     * 根据传入时间 获取上周周天时间
     * @return
     */
    public static String getLastWeekSunday() {
        SimpleDateFormat foramt = new SimpleDateFormat("yyyyMMdd");
        Calendar  cal = Calendar.getInstance();
        cal.setTime(new Date());

        if (1 == cal.get(Calendar.DAY_OF_WEEK)) {//判断当前日期是否为周末，因为周末是本周第一天，如果不向后推迟一天的到的将是下周一的零点，而不是本周周一零点
            cal.add(Calendar.DATE, -1);
        }
        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);//Calendar.SUNDAY 周天想获取周几就更换这个
        return foramt.format(cal.getTime());
    }

    /**
     * 获得上个月天数
     * @return
     */
    public static int getLastDaysOfMonth() {
        Calendar calendar =Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

    }

    /**
     * 获得上个月的第一天
     *
     * @return yyyyMMdd 格式返回
     */
    public static String getFirstDayOfLastMonth() {
        Calendar calendar =Calendar.getInstance();
        calendar.add(Calendar.MONTH,-1);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        return new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
    }
    /**
     * 获得上个月的最后一天
     *
     * @return yyyyMMdd 格式返回
     */
    public static String getLastDayOfLastMonth() {
        Calendar calendar =Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH,0);
        return new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
    }
    /**
     * 获得上个月第28天的日期
     *
     * @return yyyyMMdd 格式返回
     */
    public static String get28OfLastMonth() {
        Calendar calendar =Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH,28);
        return new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
    }

    public static Date getStepDay(Date date, int step) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(6, step);
        return new Date(calendar.getTime().getTime());
    }

    /**
     * date2比date1多的天数
     *
     * @param date1 -
     * @param date2 -
     * @return int
     */
    public static int getDiffDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        //同一年
        if (year1 != year2) {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                //闰年
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
                    timeDistance += 366;
                }
                //不是闰年
                else {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2 - day1);
        } else    //不同年
        {
            System.out.println("判断day2 - day1 : " + (day2 - day1));
            return day2 - day1;
        }
    }

    /**
     * 使用java 8的Period的对象计算两个LocalDate对象的时间差，严格按照年、月、日计算，如：2018-03-12 与 2014-05-23 相差 3 年 9 个月 17 天
     * @param startTime
     * @param endTime
     * @return 相隔时间
     */
    public static Period getPeriod(Date startTime,Date endTime) {
        LocalDate start = startTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate end = endTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        return Period.between(start, end);
    }

    /**
     * 获得当前时间的17位数字串
     *
     * @return
     */
    public static String getTimeNumber() {
        return new SimpleDateFormat(DEFAULT_FULLDATETIME_FORMAT).format(new Date());
    }
    public static void main(String[] args) throws ParseException {
        Calendar calendar =Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        Period p = getPeriod(calendar.getTime(),new Date());
        System.out.println(getFirstDayOfLastMonth());
        System.out.println(get28OfLastMonth());
        System.out.printf("目标日期距离今天的时间差：%d 年 %d 个月 %d 天\n", p.getYears(), p.getMonths(), p.getDays());
    }

}
